/* 
 * Copyright [2018] [Alex/libo(liboms@hotmail.com)]
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hyts.template.strformat;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import java.util.stream.Stream;

import com.hyts.guava.String.Strings;
import com.hyts.guava.exception.Exceptions;
import com.hyts.guava.object.Objects;
import com.hyts.jlogger.factory.LoggerFactory;
import com.hyts.template.common.BaseJavaFileTemplate;
import com.hyts.template.config.JavaTemplateConfig;
import com.hyts.template.config.JavaTemplateConfig.JavaType;

/**
 * @title DefaultJavaFileTemplate.java
 * @package com.hyts.template.freemarker
 * @description java代码的基础文件模板操作类 <br>
 *  			开发者可以从而调用此类中的方法进行<br>
 *  			构建自己的方法实例
 *
 * @see
 * @author libo/Alex
 * @email liboms@hotmail.com/liboware@163.com  
 * @date 2018年5月8日
 * @version V1.0
 */
public final class StringCodeTemplate implements BaseJavaFileTemplate {


	/* (非 Javadoc)
	 * @param baseProject
	 * @param modelName
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genPackageContent(java.lang.String, java.lang.String[])  
	 * @exception
	 */
	@Override
	public String genPackageContent(String baseProject, String... modelName) {
		//校验是否为空或者空集合
		if(Strings.isEmpty(baseProject) || Objects.isNull(modelName) || modelName.length == 0){
			Exceptions.throwRuntimeException(
					new NullPointerException("传入的基础项目架构包或者模型名称不可以为空！"));
		}
		this.getJavaCode().append(JavaTemplateConfig.JavaKeyWord.PACKAGE.getCode());
		this.getJavaCode().append(" ").append(baseProject).
				append(JavaTemplateConfig.JavaKeyWord.TOKEN_POINT.getCode()).
				append(modelName[0]).append(";").append("\n");
		return this.getJavaCode().append("\n").toString();
	}

	/* (非 Javadoc)
	 * @param javaType
	 * @param accessType
	 * @param className
	 * @param annotations
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genTypeContent(com.hyts.template.config.JavaTemplateConfig.JavaType, java.lang.String, java.lang.String, java.lang.String[])  
	 * @exception
	 */
	@Override
	public String genTypeContent(JavaType javaType, String accessType,
								 String className, String... annotations) {
		if(Strings.isEmpty(className)){
			Exceptions.throwRuntimeException(new NullPointerException("传入的className类名不许为空!"));
		}
		this.getJavaCode().append("\n");
		if(Objects.nonNull(annotations) && annotations.length > 0){
			//循环输出注解操作
			Stream.of(annotations).forEachOrdered(param->{
				if(!param.startsWith(JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode())){
					param=JavaTemplateConfig.
							JavaKeyWord.ANNOTATION.getCode()+param;
				}
				this.getJavaCode().append(param).append("\n");
			});
		}
		//public 访问修饰符
		accessType= Strings.compareBlankAndSet(accessType, JavaTemplateConfig.DefaultConfig.DEFAULT_JAVA_ACCESS_TYPE.getCode());
		//class 类
		javaType = (JavaType) Objects.compareAndGet(javaType, JavaType.TYPE);
		this.getJavaCode().append(accessType)
				.append(" ")
				.append(javaType.getCode())
				.append(" ")
				.append(className)
				.append(" {");
		return this.getJavaCode().append("\n").toString();
	}

	/* (非 Javadoc)
	 * @param importClassPath
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genImportContent(java.lang.String[])  
	 * @exception
	 */
	@Override
	public String genImportContent(String... importClassPath) {
		this.getJavaCode().append("\n");
		if(Objects.nonNull(importClassPath)){
			Stream.of(importClassPath).forEachOrdered(param->{
				this.getJavaCode().append(param).append(";").append("\n");
			});
		}
		return this.getJavaCode().append("\n").toString();
	}

	/* (非 Javadoc)
	 * @param params
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genJavaDocContent(java.util.Map)  
	 * @exception
	 */
	@Override
	public String genJavaDocContent(Map<String, String> params,String headSpace) {
		this.getJavaCode().append(headSpace).append("/**\n");
		params.forEach((key,value)->{
			if(!key.startsWith(JavaTemplateConfig.
					JavaKeyWord.ANNOTATION.getCode())){
				key=JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode()+key;
			}
			this.getJavaCode().append(headSpace).append(" * ").append(key).append(" ").append(value).append("\n");
		});
		return this.getJavaCode().append(headSpace).append(" */").toString();
	}

	/* (非 Javadoc)
	 * @param params
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genJavaCommentContent(java.util.Map)  
	 * @exception
	 */
	@Override
	public String genJavaCommentContent(Map<String, String> params,String headSpace) {
		this.getJavaCode().append("/*\n");
		params.forEach((key,value)->{
			if(!key.startsWith(JavaTemplateConfig.
					JavaKeyWord.ANNOTATION.getCode())){
				key=JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode()+key;
			}
			this.getJavaCode().append(" * ").append(key).append(" ").append(value).append("\n");
		});
		return this.getJavaCode().append(" */").toString();
	}

	/* (非 Javadoc)
	 * @param accessType
	 * @param returnType
	 * @param fieldName
	 * @param annotations
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genFieldContent(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])  
	 * @exception
	 */
	@Override
	public String genFieldContent(String accessType, String returnType,
								  String fieldName,String headSpace, String... annotations) {
		this.getJavaCode().append("\n");
		if(Objects.nonNull(annotations)) {
			Stream.of(annotations).forEach(param->{
				if(!param.startsWith(JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode())){
					param=JavaTemplateConfig.
							JavaKeyWord.ANNOTATION.getCode()+param;
				}
				this.getJavaCode().append(headSpace).append(param).append("\n");
			});
		}
		this.getJavaCode().append(headSpace).append(Strings.
				compareBlankAndSet(accessType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_ACCESS_TYPE.getCode()))
				.append(" ")
				.append(Strings.compareBlankAndSet(returnType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_RETURN_TYPE.getCode()))
				.append(" ")
				.append(fieldName);
		return this.getJavaCode().append(";").append("\n").toString();
	}

	/* (非 Javadoc)
	 * @param accessType
	 * @param returnType
	 * @param methodName
	 * @param paramList
	 * @param annotations
	 * @return
	 * @see com.hyts.template.common.JavaFileTemplate#genMethodContent(java.lang.String, java.lang.String, java.lang.String, java.util.Map, java.lang.String[])  
	 * @exception
	 */
	@Override
	public String genMethodContent(
			String accessType,
			String returnType,
			String methodName,
			Map<String, String> paramList,
			String functionBody,
			String headSpace,
			String... annotations) {
		this.getJavaCode().append("\n");
		if(Objects.nonNull(annotations)) {
			Stream.of(annotations).forEach(param->{
				if(!param.startsWith(JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode())){
					param=JavaTemplateConfig.
							JavaKeyWord.ANNOTATION.getCode()+param;
				}
				this.getJavaCode().append(headSpace).append(param).append("\n");
			});
		}
		this.getJavaCode().append(headSpace).append(Strings.
				compareBlankAndSet(accessType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_ACCESS_TYPE.getCode()))
				.append(" ")
				.append(Strings.compareBlankAndSet(returnType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_RETURN_TYPE.getCode()))
				.append(" ")
				.append(methodName);
		//key-value
		AtomicInteger index = new AtomicInteger(0);
		this.getJavaCode().append(" (");
		if(Objects.nonNull(paramList)){
			paramList.forEach((key,value)->{
				if(index.getAndIncrement() > 0)
					this.getJavaCode().append(",");
				this.getJavaCode().append(key).append(" ").append(value);
			});
		}
		this.getJavaCode().append(") {\n");
		this.getJavaCode().append(headSpace).append(functionBody).append(headSpace).append("}").append("\n");
		return null;
	}

	@Override
	public String genMethodContent(String accessType, String returnType, String methodName, Map<String, String> paramList, String functionBody, String headSpace, boolean isInterface, String... annotations) {
		this.getJavaCode().append("\n");
		if(Objects.nonNull(annotations)) {
			Stream.of(annotations).forEach(param->{
				if(!param.startsWith(JavaTemplateConfig.
						JavaKeyWord.ANNOTATION.getCode())){
					param=JavaTemplateConfig.
							JavaKeyWord.ANNOTATION.getCode()+param;
				}
				this.getJavaCode().append(headSpace).append(param).append("\n");
			});
		}
		this.getJavaCode().append(headSpace).append(Strings.
				compareBlankAndSet(accessType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_ACCESS_TYPE.getCode()))
				.append(" ")
				.append(Strings.compareBlankAndSet(returnType,
						JavaTemplateConfig.DefaultConfig.
								DEFAULT_FIELD_RETURN_TYPE.getCode()))
				.append(" ")
				.append(methodName);
		//key-value
		AtomicInteger index = new AtomicInteger(0);
		this.getJavaCode().append(" (");
		if(Objects.nonNull(paramList)){
			paramList.forEach((key,value)->{
				if(index.getAndIncrement() > 0)
					this.getJavaCode().append(",");
				this.getJavaCode().append(key).append(" ").append(value);
			});
		}
		this.getJavaCode().append(")");
		if(isInterface){
			this.getJavaCode().append(";");
		}else{
			return this.getJavaCode().append("{\n").append(headSpace).append(functionBody).append(headSpace).append("}").append("\n").toString();
		}
		return null;
	}
}
